package com.kun.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kun.alldb.support.DBManager;
import com.kun.alldb.util.ServerLoadFactoryUtil;
import com.kun.db.jdialects.springsrc.utils.Assert;
import com.kun.entity.KunDatasource;
import com.kun.enums.DsTypeEnums;
import com.kun.mapper.KunDatasourceMapper;
import com.kun.service.KunDatasourceService;
import com.kun.vo.DsFileVO;
import com.kun.vo.DsUploadVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 * @description 针对表【kun_datasource】的数据库操作Service实现
 * @createDate 2023-12-12 14:34:43
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class KunDatasourceServiceImpl extends ServiceImpl<KunDatasourceMapper, KunDatasource> implements KunDatasourceService {

    private final KunDatasourceMapper kunDatasourceMapper;

    private final String jarFolder = "/jars";
    private final String platformName = System.getProperty("os.name");

    private final String downJarsFolder = "downJars";


    @Override
    public Boolean checkDsConnection(KunDatasource kunDatasource) {
        try {
            kunDatasource.setDriverUrl(DsTypeEnums.buildDriverUrl(kunDatasource));
            DBManager dbManager = ServerLoadFactoryUtil.createDBManager(kunDatasource);
            return dbManager.checkDataSource();
        } catch (Exception e) {
            log.error("errorMessage:{}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public Boolean saveDs(KunDatasource kunDatasource) {
        Long count = kunDatasourceMapper.selectCount(Wrappers.<KunDatasource>lambdaQuery().eq(KunDatasource::getDsName, kunDatasource.getDsName()));
        if (count > 0) {
            throw new RuntimeException("连接名称不能重复");
        }
        kunDatasource.setDriverUrl(DsTypeEnums.buildDriverUrl(kunDatasource));
        return kunDatasourceMapper.insert(kunDatasource) > 0;
    }

    @Override
    public Boolean updateDs(KunDatasource kunDatasource) {
        Long count = kunDatasourceMapper.selectCount(Wrappers.<KunDatasource>lambdaQuery().eq(KunDatasource::getDsName, kunDatasource.getDsName()));
        if (count > 1) {
            throw new RuntimeException("连接名称不能重复");
        }
        kunDatasource.setDriverUrl(DsTypeEnums.buildDriverUrl(kunDatasource));
        return kunDatasourceMapper.updateById(kunDatasource) > 0;
    }

    @Override
    public DsFileVO downDriver(String dsType) {
        File downJarDirFile = new File(downJarsFolder + File.separatorChar + dsType);
        File[] listFiles = downJarDirFile.listFiles(pathname -> pathname.getName().endsWith(".jar"));
        String downFileFullPath = "";
        String originalFilename = "";
        String uploadFilePath = "";
        for (File listFile : listFiles) {
            if (listFile.isFile()) {
                downFileFullPath = listFile.getAbsolutePath();
                originalFilename = listFile.getName();
                break;
            }
        }
        Assert.notNull(originalFilename, "文件找不到");
        try (FileInputStream fileInputStream = new FileInputStream(downFileFullPath)) {
            uploadFilePath = uploadFile(fileInputStream, dsType, originalFilename);
        } catch (Exception e) {
            log.error("errorMessage:{}", e.getMessage(), e);
        }
        DsFileVO dsFileVO = new DsFileVO();
        dsFileVO.setUploadPath(uploadFilePath);
        dsFileVO.setDriverClassName(DsTypeEnums.getDriverClassName(dsType));
        return dsFileVO;
    }

    @Override
    public DsFileVO uploadDriver(String dsType, MultipartFile file) {
        String uploadFilePath = "";
        String originalFilename;
        if (ObjUtil.isNotEmpty(file)) {
            originalFilename = file.getOriginalFilename();
            if ("jar".equals(FileUtil.extName(originalFilename))) {
                // 本地创建目录
                try (InputStream inputStream = file.getInputStream();) {
                    uploadFilePath = uploadFile(inputStream, dsType, originalFilename);
                } catch (Exception e) {
                    log.error("errorMessage:{}", e.getMessage(), e);
                }
            }
        }
        DsFileVO dsFileVO = new DsFileVO();
        dsFileVO.setDriverClassName(DsTypeEnums.getDriverClassName(dsType));
        dsFileVO.setUploadPath(uploadFilePath);
        return dsFileVO;
    }

    private String uploadFile(InputStream inputStream, String dsType, String originalFilename) throws IOException {
        String uploadDir = jarFolder + File.separatorChar + dsType;
        File jarFolderDir = new File(uploadDir);
        boolean createMkdirsSuccess = true;
        if (!jarFolderDir.exists()) {
            createMkdirsSuccess = jarFolderDir.mkdirs();
        }
        if (createMkdirsSuccess) {
            // 将上传的jar包上传到uploadDir目录下
            Path path = Path.of(uploadDir).resolve(originalFilename);
            // 如果存在就覆盖 StandardCopyOption.REPLACE_EXISTING
            Files.copy(inputStream, path, StandardCopyOption.REPLACE_EXISTING);
            log.info("jar上传完成");
            return path.toString();
        }
        return "";
    }

    @Override
    public List<DsUploadVO> queryJar(String dsType) {
        String filePath = jarFolder + File.separatorChar + dsType;
        File file = new File(filePath);
        File[] listFiles = file.listFiles(pathname -> pathname.getName().endsWith(".jar"));
        List<DsUploadVO> dsUploadVOList = new ArrayList<>();
        if (ObjUtil.isNull(listFiles)) {
            return dsUploadVOList;
        }
        for (File listFile : listFiles) {
            DsUploadVO dsUploadVO = new DsUploadVO();
            dsUploadVO.setUploadFile(listFile.getPath());
            dsUploadVO.setFileName(listFile.getName());
            dsUploadVOList.add(dsUploadVO);
        }
        return dsUploadVOList;
    }

    private String getPlatformPre(String platformName) {
        String platformPre = "";
        if (platformName.contains("Windows")) {
            return "file:";
        }
        return platformPre;
    }


}




